﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Web;
using iTextSharp.text;
using iTextSharp.text.pdf;
using Transport.Core.Models.Settings;
using Transport.Services.Settings;
using Transport.Core.Models.Parcels;
using Transport.Core.Models.Customers;
using Transport.Services.Customers;

namespace Transport.Services.Parcels
{
    public class ParcelService : IParcelService
    {
        private readonly IRateMappingRepository _rateMappingRepository;
        private readonly ICustomerRepository _customerRepository;
        private readonly IRatesTableRepository _ratesTableRepository;
        private readonly IMyOfficeRepository _myOfficeRepository;

        public ParcelService(IRateMappingRepository rateMappingRepository, ICustomerRepository customerRepository,
                            IRatesTableRepository ratesTableRepository, IMyOfficeRepository myOfficeRepository)
        {
            _rateMappingRepository = rateMappingRepository;
            _customerRepository = customerRepository;
            _ratesTableRepository = ratesTableRepository;
            _myOfficeRepository = myOfficeRepository;
        }

        public decimal GetCost(int deliverFromId, int deliverToId, int totalWeight, int customerId, int myOfficeId)
        {
            var RatesTable = new List<RatesTable>();
            decimal totalCost = 0;
            //Dont need to caculate cost
            if (deliverFromId == 0 || deliverToId == 0 || totalWeight == 0)
            {
                return totalCost;
            }

            //Get discount or special rate table base on customer
            int dicountPercent = 0;
            if (customerId > 0)
            {
                var customer = _customerRepository.Search("").FirstOrDefault(p => p.CustomerId == customerId);
                if (customer != null && !customer.UseSpecialRateTable)
                {
                    RatesTable = _ratesTableRepository.GetAll().Where(p => p.CustomerId == 0 && p.MyOfficeId == myOfficeId).ToList();
                    dicountPercent = customer.DiscountPercent;
                }
                else if (customer != null && customer.UseSpecialRateTable)
                {
                    RatesTable = _ratesTableRepository.GetAll().Where(p => p.CustomerId == customer.CustomerId && p.MyOfficeId == myOfficeId).ToList();
                }
            }
            else
            {
                RatesTable = _ratesTableRepository.GetAll().Where(p => p.CustomerId == 0 && p.MyOfficeId == myOfficeId).ToList();
            }
            var rateColumn = _rateMappingRepository.GetAll()
                                                    .Where(p => p.DeliverFromId == deliverFromId
                                                            && p.DeliverToId == deliverToId && p.MyOfficeId == myOfficeId)
                                                    .Select(p => p.RateColumn)
                                                    .FirstOrDefault();
            var maximumWeight = RatesTable.Where(p => p.IsExtraColumn == false).Max(p => p.MaxWeight);
            //If Weight Be Over
            if(totalWeight > maximumWeight)
            {
                var rowMaximum = RatesTable.Where(p => p.IsExtraColumn == false)
                                             .OrderByDescending(p => p.MaxWeight)
                                             .FirstOrDefault();
                var rowExtra = RatesTable.FirstOrDefault(p => p.IsExtraColumn);
                if (rowMaximum != null && rowExtra != null)
                {
                    var weightOver = totalWeight - maximumWeight;
                    int lagerTimes = (weightOver % rowExtra.WeightOver) == 0 ? weightOver / rowExtra.WeightOver : weightOver / rowExtra.WeightOver + 1;
                    switch (rateColumn)
                    {
                        case "A":
                            {
                                totalCost = rowMaximum.PriceColumnA + (lagerTimes * rowExtra.PriceColumnA);
                                break;
                            }
                        case "B":
                            {
                                totalCost = rowMaximum.PriceColumnB + (lagerTimes * rowExtra.PriceColumnB);
                                break;
                            }
                        case "C":
                            {
                                totalCost = rowMaximum.PriceColumnC + (lagerTimes * rowExtra.PriceColumnC);
                                break;
                            }
                        case "D":
                            {
                                totalCost = rowMaximum.PriceColumnD + (lagerTimes * rowExtra.PriceColumnD);
                                break;
                            }
                        case "E":
                            {
                                totalCost = rowMaximum.PriceColumnE + (lagerTimes * rowExtra.PriceColumnE);
                                break;
                            }
                    }
                }
            }
            else //Weight In Range Tables
            {
                var rowRate = RatesTable.FirstOrDefault(p => p.MinWeight < totalWeight && p.MaxWeight >= totalWeight);
                if (rowRate != null)
                {
                    switch (rateColumn)
                    {
                        case "A":
                            {
                                totalCost = rowRate.PriceColumnA;
                                break;
                            }
                        case "B":
                            {
                                totalCost = rowRate.PriceColumnB;
                                break;
                            }
                        case "C":
                            {
                                totalCost = rowRate.PriceColumnC;
                                break;
                            }
                        case "D":
                            {
                                totalCost = rowRate.PriceColumnD;
                                break;
                            }
                        case "E":
                            {
                                totalCost = rowRate.PriceColumnE;
                                break;
                            }
                    }
                }
            }
            return dicountPercent > 0 ? totalCost - (totalCost * dicountPercent / 100) : totalCost;
        }

        public void PrintParcel(string filePath)
        {
            //Create Document class obejct and set its size to letter and give space left, right, Top, Bottom Margin
            var doc = new Document(PageSize.A4, 50, 50, 25, 25);
            PdfWriter.GetInstance(doc, new FileStream(filePath, FileMode.Create));
            //Open Document to write
            doc.Open();

            //Write some content
            var paragraph = new Paragraph("This is my first line using Paragraph.");
            var pharse = new Phrase("This is my second line using Pharse.");
            var chunk = new Chunk(" This is my third line using Chunk.");
            // Now add the above created text using different class object to our pdf document
            paragraph.Alignment = 1; 
            doc.Add(paragraph);
            doc.Add(pharse);
            doc.Add(chunk);

            //Add table
            var table = new PdfPTable(2) {WidthPercentage = 100f};

            //Add column 1
            var column1 = new PdfPCell(new Phrase("Cột 1")) {Border = Rectangle.NO_BORDER};
            table.AddCell(column1);

            //Add column 2
            var column2 = new PdfPCell(new Phrase("Cột 2")) {Border = Rectangle.BOX};
            table.AddCell(column2);

            //Add rows
            for (int i = 0; i < 100; i ++ )
            {
                var cell1 = new PdfPCell(new Phrase("row" + i.ToString(CultureInfo.InvariantCulture))) {Border = Rectangle.NO_BORDER};
                table.AddCell(cell1);

                var cell2 = new PdfPCell(new Phrase("Số liệu")) {Border = Rectangle.BOX};
                table.AddCell(cell2);
            }
            doc.Add(table);

            //Add footer
            var footer = new Paragraph(doc.BottomMargin, "footer text");
            doc.Add(footer);
            doc.Close();
        }

        public MemoryStream CreatePpf(string title)
        {
            var pdfData = new MemoryStream();
            var document = new Document(PageSize.A4, 50, 50, 25, 50);
            var pdfWriter = PdfWriter.GetInstance(document, pdfData);
            pdfWriter.ViewerPreferences = PdfWriter.PageLayoutOneColumn;

            // Our custom Header and Footer is done using Event Handler
            var pageEventHandler = new TwoColumnHeaderFooter();
            pdfWriter.PageEvent = pageEventHandler;

            // Define the page header
            //pageEventHandler.Title = title;
            //pageEventHandler.HeaderFont = FontFactory.GetFont(BaseFont.COURIER_BOLD, 10, Font.BOLD);
            //pageEventHandler.HeaderLeft = "Group";
            //pageEventHandler.HeaderRight = "1";
            var filePath = System.IO.Path.Combine(HttpContext.Current.Request.PhysicalApplicationPath, "Content\\Fonts", "times.ttf");
            BaseFont baseFont = BaseFont.CreateFont("C:\\Windows\\Fonts\\times.ttf", BaseFont.IDENTITY_H, true);
            Font defaultFont = new Font(baseFont, 12, Font.NORMAL, BaseColor.BLACK);

            document.Open();

            //Add header
            var myCompany = new Chunk("VPDD CTY TNHH TM VC TRUNG THÀNH", defaultFont);
            document.Add(myCompany);
            document.Add(new Phrase("\n"));
            var myCompanyAddress = new Chunk("Đ/C: SỐ 17 NGÁCH 43 NGÕ 64 NG.LƯƠNG BẰNG - ĐỐNG ĐA - HN", defaultFont);
            document.Add(myCompanyAddress);
            document.Add(new Phrase("\n"));
            var myCompanyContact = new Chunk("SĐT: 04.3514.9969          FAX: 04.3573.9119", defaultFont);
            document.Add(myCompanyContact);
            document.Add(new Paragraph("\r\n"));
            var myTitle = new Paragraph("B.KÊ BƯU PHẨM - HÀNG HÓA HÀ NỘI GỬI SG", new Font(baseFont, 22, Font.BOLD, BaseColor.BLACK));
            myTitle.Alignment = Element.ALIGN_CENTER;
            document.Add(myTitle);
            document.Add(new Paragraph("\r\n"));

            //From - To
            Rectangle pageSize = document.PageSize;
            var headerTable = new PdfPTable(2) { WidthPercentage = 100 };
            headerTable.DefaultCell.VerticalAlignment = Element.ALIGN_MIDDLE;
            headerTable.SetWidths(new Single[] { 1, 1 });
            var headerLeftCell = new PdfPCell(new Phrase(0, "TỪ: HÀ NỘI", defaultFont)) { BorderWidth = 0 };
            headerTable.AddCell(headerLeftCell);

            var headerRightCell = new PdfPCell(new Phrase(8, "ĐẾN: SÀI GÒN", defaultFont))
                                      {
                                          HorizontalAlignment = Element.ALIGN_RIGHT,
                                          PaddingRight = 5,
                                          BorderWidth = 0,
                                      };
            headerTable.AddCell(headerRightCell);
            document.Add(headerTable);
            //Report date
            var dateReport = new Chunk(" NGÀY: 29/06", defaultFont);
            document.Add(dateReport);
            document.Add(new Paragraph("\r\n"));

            //Add columns
            var tableColumn = new PdfPTable(6) { WidthPercentage = 100 };
            var colWidthPercentages = new Single[] { 7, 13, 35, 23, 12, 10 };
            tableColumn.DefaultCell.VerticalAlignment = Element.ALIGN_MIDDLE;
            tableColumn.SetWidths(colWidthPercentages);
            tableColumn.AddCell(new PdfPCell(new Phrase("STT", new Font(baseFont, 12, Font.BOLD, BaseColor.BLACK))) { BorderWidth = 2f, Padding = 3 });
            tableColumn.AddCell(new PdfPCell(new Phrase("SỐ BILL", new Font(baseFont, 12, Font.BOLD, BaseColor.BLACK))) { BorderWidth = 2f, Padding = 3 });
            tableColumn.AddCell(new PdfPCell(new Phrase("NƠI ĐẾN", new Font(baseFont, 12, Font.BOLD, BaseColor.BLACK))) { BorderWidth = 2f, Padding = 3 });
            tableColumn.AddCell(new PdfPCell(new Phrase("KHÁCH GỬI", new Font(baseFont, 12, Font.BOLD, BaseColor.BLACK))) { BorderWidth = 2f, Padding = 3 });
            tableColumn.AddCell(new PdfPCell(new Phrase("T.LƯỢNG", new Font(baseFont, 12, Font.BOLD, BaseColor.BLACK))) { BorderWidth = 2f, Padding = 3 });
            tableColumn.AddCell(new PdfPCell(new Phrase("GHI CHÚ", new Font(baseFont, 12, Font.BOLD, BaseColor.BLACK))) { BorderWidth = 2f, Padding = 3 });
            document.Add(tableColumn);

            //Add rows
            for (int i = 1; i <= 200; i++)
            {
                var tableRow = new PdfPTable(6) { WidthPercentage = 100 };
                tableRow.DefaultCell.VerticalAlignment = Element.ALIGN_MIDDLE;
                tableRow.SetWidths(colWidthPercentages);
                tableRow.AddCell(new PdfPCell(new Phrase(i.ToString(), defaultFont)));
                tableRow.AddCell(new PdfPCell(new Phrase((100000 + i).ToString(), defaultFont)));
                tableRow.AddCell(new PdfPCell(new Phrase("364 Cộng Hòa, P13, Q.Tân Bình, TP.Hồ Chí Minh", defaultFont)));
                tableRow.AddCell(new PdfPCell(new Phrase("Hà Việt", defaultFont)));
                tableRow.AddCell(new PdfPCell(new Phrase("3.5kg", defaultFont)));
                tableRow.AddCell(new PdfPCell(new Phrase("ĐNTT", defaultFont)));
                document.Add(tableRow);
            }

            document.Close();

            return pdfData;
        }

        public MemoryStream DownloadParcelReporting(List<ParcelReportModel> listParcel, string from, string to, string reportDate)
        {
            var pdfData = new MemoryStream();
            var document = new Document(PageSize.A4, 35, 35, 25, 50);
            var pdfWriter = PdfWriter.GetInstance(document, pdfData);
            pdfWriter.ViewerPreferences = PdfWriter.PageLayoutOneColumn;

            // Our custom Header and Footer is done using Event Handler
            var pageEventHandler = new TwoColumnHeaderFooter();
            pdfWriter.PageEvent = pageEventHandler;

            // Define the page header
            //pageEventHandler.Title = title;
            //pageEventHandler.HeaderFont = FontFactory.GetFont(BaseFont.COURIER_BOLD, 10, Font.BOLD);
            //pageEventHandler.HeaderLeft = "Group";
            //pageEventHandler.HeaderRight = "1";
            var filePath = System.IO.Path.Combine(HttpContext.Current.Request.PhysicalApplicationPath, "Content\\Fonts", "times.ttf");
            BaseFont baseFont = BaseFont.CreateFont("C:\\Windows\\Fonts\\times.ttf", BaseFont.IDENTITY_H, true);
            var fontBold = new Font(baseFont, 11, Font.BOLD, BaseColor.BLACK);
            Font defaultFont = new Font(baseFont, 12, Font.NORMAL, BaseColor.BLACK);

            document.Open();

            //Add header
            var myCompany = new Chunk("VPDD CTY TNHH TM VC TRUNG THÀNH", defaultFont);
            document.Add(myCompany);
            //document.Add(new Phrase("\n"));
            //var myCompanyAddress = new Chunk("Đ/C: SỐ 17 NGÁCH 43 NGÕ 64 NG.LƯƠNG BẰNG - ĐỐNG ĐA - HN", defaultFont);
            //document.Add(myCompanyAddress);
            //document.Add(new Phrase("\n"));
            //var myCompanyContact = new Chunk("SĐT: 04.3514.9969          FAX: 04.3573.9119", defaultFont);
            //document.Add(myCompanyContact);
            document.Add(new Paragraph("\r\n"));
            var myTitle = new Paragraph("B.KÊ BƯU PHẨM - HÀNG HÓA", new Font(baseFont, 22, Font.BOLD, BaseColor.BLACK));
            myTitle.Alignment = Element.ALIGN_CENTER;
            document.Add(myTitle);
            document.Add(new Paragraph("\r\n"));

            //From - To
            Rectangle pageSize = document.PageSize;
            var headerTable = new PdfPTable(2) { WidthPercentage = 100 };
            headerTable.DefaultCell.VerticalAlignment = Element.ALIGN_MIDDLE;
            headerTable.SetWidths(new Single[] { 1, 1 });
            var headerLeftCell = new PdfPCell(new Phrase(0, "TỪ: " + from, defaultFont)) { BorderWidth = 0 };
            headerTable.AddCell(headerLeftCell);

            var headerRightCell = new PdfPCell(new Phrase(8, "ĐẾN: " + to, defaultFont))
            {
                HorizontalAlignment = Element.ALIGN_RIGHT,
                PaddingRight = 5,
                BorderWidth = 0,
            };
            headerTable.AddCell(headerRightCell);
            document.Add(headerTable);
            //Report date
            var dateReport = new Chunk(" NGÀY: " + reportDate, defaultFont);
            document.Add(dateReport);
            document.Add(new Paragraph("\r\n"));

            //Add columns
            var tableColumn = new PdfPTable(6) { WidthPercentage = 100 };
            var colWidthPercentages = new Single[] { 7, 18, 35, 21, 12, 7 };
            tableColumn.DefaultCell.VerticalAlignment = Element.ALIGN_MIDDLE;
            tableColumn.SetWidths(colWidthPercentages);
            tableColumn.AddCell(new PdfPCell(new Phrase("STT", new Font(baseFont, 12, Font.BOLD, BaseColor.BLACK))) { BorderWidth = 2f, Padding = 3, HorizontalAlignment = Element.ALIGN_CENTER});
            tableColumn.AddCell(new PdfPCell(new Phrase("SỐ BILL", new Font(baseFont, 12, Font.BOLD, BaseColor.BLACK))) { BorderWidth = 2f, Padding = 3, HorizontalAlignment = Element.ALIGN_CENTER });
            tableColumn.AddCell(new PdfPCell(new Phrase("NƠI ĐẾN", new Font(baseFont, 12, Font.BOLD, BaseColor.BLACK))) { BorderWidth = 2f, Padding = 3, HorizontalAlignment = Element.ALIGN_CENTER });
            tableColumn.AddCell(new PdfPCell(new Phrase("KHÁCH GỬI", new Font(baseFont, 12, Font.BOLD, BaseColor.BLACK))) { BorderWidth = 2f, Padding = 3, HorizontalAlignment = Element.ALIGN_CENTER });
            tableColumn.AddCell(new PdfPCell(new Phrase("T.LƯỢNG", new Font(baseFont, 12, Font.BOLD, BaseColor.BLACK))) { BorderWidth = 2f, Padding = 3, HorizontalAlignment = Element.ALIGN_CENTER });
            tableColumn.AddCell(new PdfPCell(new Phrase("GHI CHÚ", new Font(baseFont, 12, Font.BOLD, BaseColor.BLACK))) { BorderWidth = 2f, Padding = 3, HorizontalAlignment = Element.ALIGN_CENTER });
            document.Add(tableColumn);

            //Add rows
            var no = 1;
            foreach (var item in listParcel)
            {
                var tableRow = new PdfPTable(6) { WidthPercentage = 100 };
                tableRow.DefaultCell.VerticalAlignment = Element.ALIGN_MIDDLE;
                tableRow.SetWidths(colWidthPercentages);
                tableRow.AddCell(new PdfPCell(new Phrase(no.ToString(), defaultFont)));
                tableRow.AddCell(new PdfPCell(new Phrase(item.TrackingNumbers, defaultFont)));
                tableRow.AddCell(new PdfPCell(new Phrase(item.AddressTo, defaultFont)));
                tableRow.AddCell(new PdfPCell(new Phrase(item.CustomerName, defaultFont)));
                tableRow.AddCell(new PdfPCell(new Phrase(item.WeightString, defaultFont)));
                tableRow.AddCell(new PdfPCell(new Phrase(item.Note, defaultFont)));
                document.Add(tableRow);
                no++;
            }

            document.Close();

            return pdfData;
        }

        public MemoryStream DownloadParcelCustomerReporting(List<ParcelCustomerReportModel> listParcel, string fromDate, string toDate, List<Customer> customers, int paymentType, int myOfficeId)
        {
            var pdfData = new MemoryStream();
            var document = new Document(PageSize.A4, 35, 35, 25, 50);
            var pdfWriter = PdfWriter.GetInstance(document, pdfData);
            pdfWriter.ViewerPreferences = PdfWriter.PageLayoutOneColumn;

            // Our custom Header and Footer is done using Event Handler
            var pageEventHandler = new TwoColumnHeaderFooter();
            pdfWriter.PageEvent = pageEventHandler;

            // Define the page header
            //pageEventHandler.Title = title;
            //pageEventHandler.HeaderFont = FontFactory.GetFont(BaseFont.COURIER_BOLD, 10, Font.BOLD);
            //pageEventHandler.HeaderLeft = "Group";
            //pageEventHandler.HeaderRight = "1";
            var filePath = System.IO.Path.Combine(HttpContext.Current.Request.PhysicalApplicationPath, "Content\\Fonts", "times.ttf");
            var baseFont = BaseFont.CreateFont("C:\\Windows\\Fonts\\times.ttf", BaseFont.IDENTITY_H, true);
            var defaultFont = new Font(baseFont, 9, Font.NORMAL, BaseColor.BLACK);
            var fontBold = new Font(baseFont, 9, Font.BOLD, BaseColor.BLACK);
            document.Open();

            //Add header
            var tableColumnHearder = new PdfPTable(2) { WidthPercentage = 100 };
            var colWidthPercentagesHearder = new Single[] { 50, 50 };
            tableColumnHearder.DefaultCell.VerticalAlignment = Element.ALIGN_MIDDLE;
            tableColumnHearder.SetWidths(colWidthPercentagesHearder);

            string imagepath = Path.Combine(HttpContext.Current.Request.PhysicalApplicationPath, "Content\\images", "Logo TrungThanh Express.jpg");
            Image img = Image.GetInstance(imagepath);
            img.ScaleToFit(200f, 100f);
            img.Alignment = Image.ALIGN_LEFT;
            img.IndentationLeft = 0f;
            img.SpacingAfter = 9f;
            img.BorderWidthTop = 5f;
            img.BorderColorTop = BaseColor.WHITE;
            tableColumnHearder.AddCell(new PdfPCell(img) { BorderWidth = 0, Padding = 3, HorizontalAlignment = Element.ALIGN_LEFT });

            var office = _myOfficeRepository.GetById(myOfficeId);
            var myCompany = new Paragraph(office.OfficeName + Environment.NewLine + "Đ/C: " + office.Address + Environment.NewLine + "SĐT: " + office.PhoneNumber + (string.IsNullOrEmpty(office.Fax) ? string.Empty : " FAX: " + office.Fax), defaultFont);
            myCompany.Alignment = Element.ALIGN_RIGHT;
            tableColumnHearder.AddCell(new PdfPCell(myCompany) { BorderWidth = 0, Padding = 3, HorizontalAlignment = Element.ALIGN_RIGHT });
            document.Add(tableColumnHearder);

            //End header

            document.Add(new Paragraph("\r\n"));
            var reportName = string.Empty;
            switch (paymentType)
            {
                case (int)PaymentTypes.EnumPaymentTypes.Debt:
                    reportName = "NỢ";
                    break;
                case (int)PaymentTypes.EnumPaymentTypes.Cash:
                    reportName = "TIỀN MẶT";
                    break;
                case (int)PaymentTypes.EnumPaymentTypes.Collection:
                    reportName = "THU HỘ";
                    break;
                default:
                    reportName = "TỔNG HỢP";
                    break;
            }
            var myTitle = new Paragraph("BẢNG KÊ "+ reportName + " CHI TIẾT", new Font(baseFont, 22, Font.BOLD, BaseColor.BLACK));
            myTitle.Alignment = Element.ALIGN_CENTER;
            document.Add(myTitle);
            document.Add(new Paragraph("\r\n"));

            //From - To
            var headerTable = new PdfPTable(2) { WidthPercentage = 100 };
            headerTable.DefaultCell.VerticalAlignment = Element.ALIGN_MIDDLE;
            headerTable.SetWidths(new Single[] { 1, 1 });
            var headerLeftCell = new PdfPCell(new Phrase(0, "TỪ NGÀY: " + fromDate, defaultFont))
            {
                HorizontalAlignment = Element.ALIGN_RIGHT,
                PaddingRight = 5,
                BorderWidth = 0
            };
            headerTable.AddCell(headerLeftCell);

            var headerRightCell = new PdfPCell(new Phrase(8, "ĐẾN NGÀY: " + toDate, defaultFont))
            {
                HorizontalAlignment = Element.ALIGN_LEFT,
                PaddingLeft = 5,
                BorderWidth = 0,
            };
            headerTable.AddCell(headerRightCell);
            document.Add(headerTable);

            //Split the columns
            var colWidthPercentages = new Single[] { 5, 11, 11, 11, 10, 13, 13, 13, 13 };

            //Report all customers
            var no = 1;
            decimal totalCost = 0;
            foreach (var customer in customers)
            {
                ReportingPerCustomer(listParcel.Where(p => p.CustomerId == customer.CustomerId || (p.CustomerId == null && customer.CustomerId == -1)).ToList(), customer,
                    document, colWidthPercentages, defaultFont, fontBold, no, ref totalCost);
            }

            document.Add(new Paragraph("\r\n"));

            //Total cost
            if (customers.Count() > 1)
            {
                var vat = totalCost / 10;
                var tablefooter = new PdfPTable(9) { WidthPercentage = 100 };
                tablefooter.DefaultCell.VerticalAlignment = Element.ALIGN_MIDDLE;
                tablefooter.SetWidths(colWidthPercentages);
                tablefooter.AddCell(new PdfPCell(new Phrase("TỔNG CỘNG: " + String.Format("{0:0,0}", vat + totalCost), fontBold)) { BorderWidth = 0, Colspan = 9, HorizontalAlignment = Element.ALIGN_RIGHT });
                document.Add(tablefooter);
            }

            //Add footer info
            var footerTableInfo = new PdfPTable(2) { WidthPercentage = 100 };
            footerTableInfo.DefaultCell.VerticalAlignment = Element.ALIGN_MIDDLE;
            footerTableInfo.SetWidths(new Single[] { 1, 1 });
            var footerLeftCell = new PdfPCell(new Phrase(0, "Quý khách có thể thanh toán bằng tiền mặt hoặc chuyển khoản.", defaultFont))
            {
                HorizontalAlignment = Element.ALIGN_LEFT,
                BorderWidth = 0
            };
            footerTableInfo.AddCell(footerLeftCell);

            var footerRightCell = new PdfPCell(new Phrase(8, "NGÀY: ", defaultFont))
            {
                HorizontalAlignment = Element.ALIGN_RIGHT,
                PaddingRight = 100,
                BorderWidth = 0,
            };
            footerTableInfo.AddCell(footerRightCell);
            document.Add(footerTableInfo);

            document.Close();

            return pdfData;
        }

        public void AddOutline(PdfWriter writer, string title, float position)
        {
            var destination = new PdfDestination(PdfDestination.FITH, position);
            var outline = new PdfOutline(writer.DirectContent.RootOutline, destination, title);
            writer.DirectContent.AddOutline(outline, "Name = " + title);
        }

        private void ReportingPerCustomer(IEnumerable<ParcelCustomerReportModel> listParcel, Customer customer, Document document,
                                         float[] colWidthPercentages, Font defaultFont, Font fontBold, int no, ref decimal totalCostOut)
        {
            if (!listParcel.Any())
            {
                return;
            }
            if (customer.CustomerId > 0)
            {
                //Add customer info
                var tableCustomerInfo = new PdfPTable(9) { WidthPercentage = 100 };
                tableCustomerInfo.DefaultCell.VerticalAlignment = Element.ALIGN_MIDDLE;
                tableCustomerInfo.SetWidths(colWidthPercentages);
                tableCustomerInfo.AddCell(new PdfPCell(new Phrase("KHÁCH HÀNG:", defaultFont)) { Colspan = 2, BorderWidthRight = 0, BorderWidthBottom = 0, BackgroundColor = BaseColor.GRAY });
                tableCustomerInfo.AddCell(new PdfPCell(new Phrase(customer.CustomerCode, fontBold)) { Colspan = 1, BorderWidthLeft = 0, BorderWidthRight = 0, BorderWidthBottom = 0, BackgroundColor = BaseColor.GRAY });
                tableCustomerInfo.AddCell(new PdfPCell(new Phrase("ĐỊA CHỈ:", defaultFont)) { Colspan = 6, BorderWidthLeft = 0, BorderWidthBottom = 0, BackgroundColor = BaseColor.GRAY });
                //tableCustomerInfo.AddCell(new PdfPCell(new Phrase("MÃ SỐ THUẾ", defaultFont)) { Colspan = 2 });
                //tableCustomerInfo.AddCell(new PdfPCell(new Phrase("TUYẾN CÔNG NỢ", defaultFont)));
                document.Add(tableCustomerInfo);

                //Add customer info
                var tableCustomerInfo1 = new PdfPTable(9) { WidthPercentage = 100 };
                tableCustomerInfo1.DefaultCell.VerticalAlignment = Element.ALIGN_MIDDLE;
                tableCustomerInfo1.SetWidths(colWidthPercentages);
                tableCustomerInfo1.AddCell(new PdfPCell(new Phrase(customer.CustomerName, fontBold)) { Colspan = 3, BorderWidthRight = 0, BorderWidthTop = 0, BackgroundColor = BaseColor.GRAY });
                tableCustomerInfo1.AddCell(new PdfPCell(new Phrase(customer.Address, fontBold)) { Colspan = 6, BorderWidthLeft = 0, BorderWidthTop = 0, BackgroundColor = BaseColor.GRAY });
                document.Add(tableCustomerInfo1);
            }
            else
            {
                //Add customer info
                var tableCustomerInfo = new PdfPTable(9) { WidthPercentage = 100 };
                tableCustomerInfo.DefaultCell.VerticalAlignment = Element.ALIGN_MIDDLE;
                tableCustomerInfo.SetWidths(colWidthPercentages);
                tableCustomerInfo.AddCell(new PdfPCell(new Phrase("KHÁCH HÀNG:", defaultFont)) { Colspan = 2, BorderWidthRight = 0, BorderWidthBottom = 0, BackgroundColor = BaseColor.GRAY });
                tableCustomerInfo.AddCell(new PdfPCell(new Phrase("", fontBold)) { Colspan = 1, BorderWidthLeft = 0, BorderWidthRight = 0, BorderWidthBottom = 0, BackgroundColor = BaseColor.GRAY });
                tableCustomerInfo.AddCell(new PdfPCell(new Phrase("ĐỊA CHỈ:", defaultFont)) { Colspan = 6, BorderWidthLeft = 0, BorderWidthBottom = 0, BackgroundColor = BaseColor.GRAY });
                //tableCustomerInfo.AddCell(new PdfPCell(new Phrase("MÃ SỐ THUẾ", defaultFont)) { Colspan = 2 });
                //tableCustomerInfo.AddCell(new PdfPCell(new Phrase("TUYẾN CÔNG NỢ", defaultFont)));
                document.Add(tableCustomerInfo);

                //Add customer info
                var tableCustomerInfo1 = new PdfPTable(9) { WidthPercentage = 100 };
                tableCustomerInfo1.DefaultCell.VerticalAlignment = Element.ALIGN_MIDDLE;
                tableCustomerInfo1.SetWidths(colWidthPercentages);
                tableCustomerInfo1.AddCell(new PdfPCell(new Phrase("Khách lẻ", fontBold)) { Colspan = 3, BorderWidthRight = 0, BorderWidthTop = 0, BackgroundColor = BaseColor.GRAY });
                tableCustomerInfo1.AddCell(new PdfPCell(new Phrase("", fontBold)) { Colspan = 6, BorderWidthLeft = 0, BorderWidthTop = 0, BackgroundColor = BaseColor.GRAY });
                document.Add(tableCustomerInfo1);
            }

            //Add columns
            var tableColumn = new PdfPTable(9) { WidthPercentage = 100 };
            tableColumn.DefaultCell.VerticalAlignment = Element.ALIGN_MIDDLE;
            tableColumn.SetWidths(colWidthPercentages);
            tableColumn.AddCell(new PdfPCell(new Phrase("STT", fontBold)) { HorizontalAlignment = Element.ALIGN_CENTER });
            tableColumn.AddCell(new PdfPCell(new Phrase("NGÀY GỬI", fontBold)) { HorizontalAlignment = Element.ALIGN_CENTER });
            tableColumn.AddCell(new PdfPCell(new Phrase("SỐ VẬN ĐƠN", fontBold)) { HorizontalAlignment = Element.ALIGN_CENTER });
            tableColumn.AddCell(new PdfPCell(new Phrase("NƠI ĐẾN", fontBold)) { HorizontalAlignment = Element.ALIGN_CENTER });
            tableColumn.AddCell(new PdfPCell(new Phrase("T.LƯỢNG", fontBold)) { HorizontalAlignment = Element.ALIGN_CENTER });
            tableColumn.AddCell(new PdfPCell(new Phrase("CƯỚC CHÍNH", fontBold)) { HorizontalAlignment = Element.ALIGN_CENTER });
            tableColumn.AddCell(new PdfPCell(new Phrase("THUẾ VAT", fontBold)) { HorizontalAlignment = Element.ALIGN_CENTER });
            tableColumn.AddCell(new PdfPCell(new Phrase("TỔNG CỘNG", fontBold)) { HorizontalAlignment = Element.ALIGN_CENTER });
            tableColumn.AddCell(new PdfPCell(new Phrase("GHI CHÚ", fontBold)) { HorizontalAlignment = Element.ALIGN_CENTER });
            document.Add(tableColumn);

            //Add rows
            var totalWeight = 0;
            decimal totalCost = 0;
            foreach (var item in listParcel)
            {
                var tableRow = new PdfPTable(9) { WidthPercentage = 100 };
                tableRow.DefaultCell.VerticalAlignment = Element.ALIGN_MIDDLE;
                tableRow.SetWidths(colWidthPercentages);
                tableRow.AddCell(new PdfPCell(new Phrase(no.ToString(), defaultFont)) { HorizontalAlignment = Element.ALIGN_CENTER });
                tableRow.AddCell(new PdfPCell(new Phrase(item.DateOfSendingDisplay, defaultFont)) { HorizontalAlignment = Element.ALIGN_CENTER });
                tableRow.AddCell(new PdfPCell(new Phrase(item.TrackingNumbers.ToUpper(), defaultFont)) { HorizontalAlignment = Element.ALIGN_CENTER });
                tableRow.AddCell(new PdfPCell(new Phrase(item.DeliverTo, defaultFont)) { HorizontalAlignment = Element.ALIGN_CENTER });
                tableRow.AddCell(new PdfPCell(new Phrase(item.WeightDisplay, defaultFont)) { HorizontalAlignment = Element.ALIGN_RIGHT });
                tableRow.AddCell(new PdfPCell(new Phrase(item.CostDisplay, defaultFont)) { HorizontalAlignment = Element.ALIGN_RIGHT });
                tableRow.AddCell(new PdfPCell(new Phrase(item.Vat, defaultFont)) { HorizontalAlignment = Element.ALIGN_RIGHT });
                tableRow.AddCell(new PdfPCell(new Phrase(item.TotalCostDisplay, defaultFont)) { HorizontalAlignment = Element.ALIGN_RIGHT });
                tableRow.AddCell(new PdfPCell(new Phrase(item.Note, defaultFont)));
                document.Add(tableRow);
                no++;
                totalWeight += item.Weight;
                totalCost += item.Cost;
            }
            totalCostOut += totalCost;
            var vat = totalCost / 10;
            //Add table total
            var tableTotal = new PdfPTable(9) { WidthPercentage = 100 };
            tableTotal.DefaultCell.VerticalAlignment = Element.ALIGN_MIDDLE;
            tableTotal.SetWidths(colWidthPercentages);
            tableTotal.AddCell(new PdfPCell(new Phrase("TỔNG CỘNG", fontBold)) { Colspan = 4, PaddingLeft = 10 });
            tableTotal.AddCell(new PdfPCell(new Phrase(String.Format("{0:0,0}", totalWeight), defaultFont)) { HorizontalAlignment = Element.ALIGN_RIGHT });
            tableTotal.AddCell(new PdfPCell(new Phrase(String.Format("{0:0,0}", totalCost), defaultFont)) { HorizontalAlignment = Element.ALIGN_RIGHT });
            tableTotal.AddCell(new PdfPCell(new Phrase(String.Format("{0:0,0}", vat), defaultFont)) { HorizontalAlignment = Element.ALIGN_RIGHT });
            tableTotal.AddCell(new PdfPCell(new Phrase(String.Format("{0:0,0}", vat + totalCost), defaultFont)) { HorizontalAlignment = Element.ALIGN_RIGHT });
            tableTotal.AddCell(new PdfPCell(new Phrase(string.Empty, defaultFont)) { HorizontalAlignment = Element.ALIGN_RIGHT });
            document.Add(tableTotal);

            //Add table footer
            var tablefooter = new PdfPTable(9) { WidthPercentage = 100 };
            tablefooter.DefaultCell.VerticalAlignment = Element.ALIGN_MIDDLE;
            tablefooter.SetWidths(colWidthPercentages);
            var wordsTotalCost = NumberToWords.ChangeCurrencyToWords(vat + totalCost);
            tablefooter.AddCell(new PdfPCell(new Phrase("Thành tiền: " + char.ToUpper(wordsTotalCost[0]) + wordsTotalCost.Substring(1) + "./.", fontBold)) { Colspan = 9 });
            document.Add(tablefooter);
        }
    }

    public class TwoColumnHeaderFooter : PdfPageEventHelper
    {
        // This is the contentbyte object of the writer
        PdfContentByte _cb;

        // we will put the final number of pages in a template
        PdfTemplate _template;

        // this is the BaseFont we are going to use for the header / footer
        BaseFont _bf;

        // This keeps track of the creation time
        DateTime _printTime = DateTime.Now;

        #region Properties

        public string Title { get; set; }

        public string HeaderLeft { get; set; }

        public string HeaderRight { get; set; }

        public Font HeaderFont { get; set; }

        public Font FooterFont { get; set; }

        #endregion

        // we override the onOpenDocument method
        public override void OnOpenDocument(PdfWriter writer, Document document)
        {
            try
            {
                _printTime = DateTime.Now;
                _bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
                _cb = writer.DirectContent;
                _template = _cb.CreateTemplate(50, 50);
            }
            catch (DocumentException)
            {
            }
            catch (IOException)
            {
            }
        }

        public override void OnStartPage(PdfWriter writer, Document document)
        {
            base.OnStartPage(writer, document);

            //Rectangle pageSize = document.PageSize;

            //if (Title != string.Empty)
            //{
            //    _cb.BeginText();
            //    _cb.SetFontAndSize(_bf, 15);
            //    _cb.SetRGBColorFill(50, 50, 200);
            //    _cb.SetTextMatrix(pageSize.GetLeft(40), pageSize.GetTop(40));
            //    _cb.ShowText(Title);
            //    _cb.EndText();
            //}

            //if (HeaderLeft + HeaderRight != string.Empty)
            //{
            //    var headerTable = new PdfPTable(2);
            //    headerTable.DefaultCell.VerticalAlignment = Element.ALIGN_MIDDLE;
            //    headerTable.TotalWidth = pageSize.Width - 80;
            //    headerTable.SetWidthPercentage(new float[] { 45, 45 }, pageSize);

            //    var headerLeftCell = new PdfPCell(new Phrase(8, HeaderLeft, HeaderFont)) { Padding = 5, PaddingBottom = 8, BorderWidthRight = 0 };
            //    headerTable.AddCell(headerLeftCell);

            //    var headerRightCell = new PdfPCell(new Phrase(8, HeaderRight, HeaderFont))
            //                              {
            //                                  HorizontalAlignment = Element.ALIGN_RIGHT,
            //                                  Padding = 5,
            //                                  PaddingBottom = 8,
            //                                  BorderWidthLeft = 0
            //                              };
            //    headerTable.AddCell(headerRightCell);

            //    _cb.SetRGBColorFill(0, 0, 0);
            //    headerTable.WriteSelectedRows(0, -1, pageSize.GetLeft(40), pageSize.GetTop(50), _cb);
            //}
        }

        public override void OnEndPage(PdfWriter writer, Document document)
        {
            base.OnEndPage(writer, document);

            int pageN = writer.PageNumber;
            var text = "Trang " + pageN + "/";
            var len = _bf.GetWidthPoint(text, 8);

            Rectangle pageSize = document.PageSize;

            _cb.SetRGBColorFill(100, 100, 100);

            _cb.BeginText();
            _cb.SetFontAndSize(_bf, 8);
            _cb.SetTextMatrix(pageSize.GetLeft(40), pageSize.GetBottom(30));
            _cb.ShowText(text);
            _cb.EndText();

            _cb.AddTemplate(_template, pageSize.GetLeft(40) + len, pageSize.GetBottom(30));

            //_cb.BeginText();
            //_cb.SetFontAndSize(_bf, 8);
            //_cb.ShowTextAligned(PdfContentByte.ALIGN_RIGHT,
            //    "Printed On " + _printTime.ToString(CultureInfo.InvariantCulture),
            //    pageSize.GetRight(40),
            //    pageSize.GetBottom(30), 0);
            //_cb.EndText();
        }

        public override void OnCloseDocument(PdfWriter writer, Document document)
        {
            base.OnCloseDocument(writer, document);

            _template.BeginText();
            _template.SetFontAndSize(_bf, 8);
            _template.SetTextMatrix(0, 0);
            _template.ShowText("" + (writer.PageNumber - 1));
            _template.EndText();
        }

    }
}
